﻿#include "MqttAdapter.h"
#include"kits/Config.h"

static int msgArrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
    Q_UNUSED(topicLen)
    MqttAdapter* mqttAdapter = (MqttAdapter*)context;
    mqttAdapter->recvMessage((char*)message->payload,topicName);
    MQTTClient_freeMessage(&message);
    MQTTClient_free(topicName);
    return 1;
}

static void connectionLost(void* context, char* cause){
    MqttAdapter* mqttAdapter = (MqttAdapter*)context;
    mqttAdapter->connectLost(cause);
}

MqttAdapter::MqttAdapter(QObject *parent):QObject(parent)
{
    MQTTClient_nameValue* ver = MQTTClient_getVersionInfo();
    xPrint<<ver->name<<ver->value;
}

MqttAdapter::~MqttAdapter()
{
    MQTTClient_disconnect(mClient, 10000);
    MQTTClient_destroy(&mClient);
}

bool MqttAdapter::initMqtt(const QString &clientId)
{
    if(mhasConn) return true;
    //连接参数设置
    MQTTClient_connectOptions options = MQTTClient_connectOptions_initializer;
    MQTTClient_create(&mClient,MQTT_ADDRESS,clientId.toStdString().c_str(),MQTTCLIENT_PERSISTENCE_NONE,NULL);
    options.keepAliveInterval = 20;
    options.cleansession = 1;
    options.username = MQTT_USERNAME;
    options.password = MQTT_PASSWORD;
    //设置回调
    MQTTClient_setCallbacks(mClient,(void*)this,connectionLost,msgArrvd,NULL);
    int errCode = 0;
    if((errCode = MQTTClient_connect(mClient,&options)) != MQTTCLIENT_SUCCESS){
        printConnectError(errCode);
        return false;
    }
    mhasConn = true;
    return true;


}
//订阅主题
void MqttAdapter::subScribe(const QString &toptic)
{
    MQTTClient_subscribe(mClient,toptic.toStdString().c_str(),MQTT_QOS);
}

//发布消息
int MqttAdapter::publicMessage(const QString &message, const QString &topic)
{
    QByteArray sendArray = message.toLatin1();
    MQTTClient_deliveryToken token;
    MQTTClient_message pubmsg = MQTTClient_message_initializer;
    pubmsg.payload = (void*)sendArray.data();
    pubmsg.payloadlen = sendArray.size();
    pubmsg.qos = MQTT_QOS;
    pubmsg.retained = 0;
   int rc =  MQTTClient_publishMessage(mClient,topic.toLatin1(), &pubmsg, &token);
   if(rc != MQTTCLIENT_SUCCESS){
          return rc;
   }
   return  MQTTClient_waitForCompletion(mClient, token, MQTT_TIMEOUT);
}

//收到消息
void MqttAdapter::recvMessage(const char *data, char *topic)
{
    xPrint<<data<<topic;
}

void MqttAdapter::connectLost(char *cause)
{
    xErr<<cause;
    mhasConn = false;
}

void MqttAdapter::printConnectError(const int errCode) const
{
    switch (errCode) {
     case 1:
        xErr<<"Unacceptable protocol version";
        break;
     case 2:
        xErr<<"Identifier rejected";
        break;
    case 3:
        xErr<<"Server unavailable";
        break;
    case 4:
        xErr<<"Bad user name or password";
        break;
    case 5:
        xErr<<"Not authorized";
        break;
    default:
        xErr<<"unknow Error";
        break;
    }
}
